﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using G3.AI;
using G3.Controller;
using G3.State;
using dnAnalytics.LinearAlgebra;

namespace G3
{
    public partial class MainWindow : Form
    {
        public MainWindow()
        {
            InitializeComponent();
            isHumenSelected = false;
            //TODO:: lehetne egy congi fájlba rakni az egészet -> XML
            Parameters.LoadParameters(System.Windows.Forms.Application.StartupPath + "\\Data\\param.conf");
            myController = Controller.Controller.GetOnlyInstance();
            myController.SetGraphicPanel(this);
            AIGruopBox.Hide();
        }


        #region DataTags        
        private G3.Controller.Controller myController;
        private IDriver myDriver;
        //private Parameters myParameters;

        bool isHumenSelected;
        #endregion


        #region Interface
        /// <summary>
        /// A garfika frissítése
        /// </summary>
        /// <param name="carPos">az autó új pozíciója</param>
        /// <param name="carAngle">az autó új szöge 0..2pi</param>
        public void GraphRefresh(Point carPos, double carAngle)
        {
            myGraphicPanel.RefreshMap(carPos, carAngle);
        }        
        

        /// <summary>
        /// Gázpedál grafikus megjelenítése
        /// </summary>
        /// <param name="value">-100..100</param>
        public void SetAccelerator(int value)
        {
            if (value > 100)
            {
                value = 100;
            }
            else if (value < -100)
            {
                value = -100;
            }

                if (value >= 0)
                {
                    GasprogressBar.Value = value;
                    BrakeprogressBar.Value = 0;
                }
                else
                {
                    BrakeprogressBar.Value = -value;
                    GasprogressBar.Value = 0;
                }                       
        }

        /// <summary>
        /// Kormány állás grafikus megjelenítése
        /// </summary>
        /// <param name="value">-100..100</param>
        public void SetWheel(int value)
        {
            if (value >= -100 && value <= 100)
            {
                WheeltrackBar.Value = value;
            }
        }
        #endregion
       
        
        #region Implementation
        /// <summary>
        /// A vezető indítása vagy szüneteltetése(?)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartButton_Click(object sender, EventArgs e)
        {

            if (radioButton_human.Checked)
            {
                myGraphicPanel.Focus();                
                isHumenSelected = true;
                myDriver=new HumanDriver();
                graphicViewTimer.Start();
            }
            else if (radioButton_rule.Checked)
            {
                isHumenSelected = false;
                myDriver = new Evolution();
                SetAIInterface("Evolution");
            }
            else if (radioButton_spec.Checked)
            {
                isHumenSelected=false;
                myDriver = new HybridDriver();
                SetAIInterface("HybridDriver");
            }
            else if(radioButton_uni.Checked)
            {
                isHumenSelected=false;
                myDriver=new UniversalNeuralDriver();
                SetAIInterface("Neural");
            }

            radioButton_human.Enabled = radioButton_rule.Enabled
            = radioButton_spec.Enabled = radioButton_uni.Enabled = StartButton.Enabled = false;
            StopButton.Enabled = true;
            StartButton.Enabled = false;
            
        }

        public void SetAIInterface(string name)
        {
            AIGruopBox.Show();
            AIGruopBox.Text = name;
        }

        /// <summary>
        /// A vezető megállítása
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StopButton_Click(object sender, EventArgs e)
        {
            if (isHumenSelected)
            {                
                //autó visszarakása, controller reset            
                myController.Reset();
                myGraphicPanel.ResetCar();
                graphicViewTimer.Stop();

                isHumenSelected = false;
            }
            else
            {
                AIGruopBox.Hide();
                button_ai_stop_Click(button_ai_stop, null);
            }

            radioButton_human.Enabled = radioButton_rule.Enabled
                    = radioButton_spec.Enabled = radioButton_uni.Enabled = StartButton.Enabled = true;
            StopButton.Enabled = false;
            StartButton.Enabled = true;
        }

        /// <summary>
        /// Térkép betöltése
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Loadbutton_Click(object sender, EventArgs e)
        {
            imageOpenFileDialog.Title = "Select the map image";
            imageOpenFileDialog.FilterIndex = 1;
            if (imageOpenFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                myGraphicPanel.SetMap(imageOpenFileDialog.FileName);
                myController.MapLoaded();
                pictureBox_map.BackgroundImage = new Bitmap(imageOpenFileDialog.FileName);
                pictureBox_map.BackgroundImageLayout = ImageLayout.Zoom;

                //Map.SaveToTextFile("hungaroring_gen.txt");
            }

            

        }

        private void carbLoadButton_Click(object sender, EventArgs e)
        {
            imageOpenFileDialog.Title = "Select the car image";
            imageOpenFileDialog.FilterIndex = 2;
            if (DialogResult.OK == imageOpenFileDialog.ShowDialog(this))
            {
                Image carImage = new Bitmap(imageOpenFileDialog.FileName);
                myGraphicPanel.SetCar(carImage);
                carPictureBox.BackgroundImage = carImage;
            }
        }

        private void Savebutton_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this, "Not implemented yet!");
        }
        #endregion


        #region Human driver handling        
        private void myGraphicPanel_KeyDown(object sender, KeyEventArgs e)
        {
            if (!isHumenSelected) return;
            HumanDriver myHD = (HumanDriver)myDriver;
            myHD.HandleInteraction(e.KeyCode, true);
            
        }

        private void myGraphicPanel_KeyUp(object sender, KeyEventArgs e)
        {
            if (!isHumenSelected) return;
            HumanDriver myHD = (HumanDriver)myDriver;
            myHD.HandleInteraction(e.KeyCode, false);
        }
        #endregion

        private void graphicViewTimer_Tick(object sender, EventArgs e)
        {
            myDriver.Think();

            ShowGraphics();

            /*Matrix fov = Map.GetFieldOfVision(myController.AttachedState.CarPosition, 
                myController.AttachedState.CarOrientationRadian);

            Image fovImage = GenerateBitmapFromMatrix(fov);
            pictureBox_fov.BackgroundImage = fovImage;*/

            //TODO:: set carwheel and throotle position
            
            //Image            
            //beep :)            

        }

        public void ShowGraphics()
        {
            KeyValuePair<Pair, double> posAndAngel = myController.GetCarPositionAndAngle();
            this.GraphRefresh(
                new Point((int)Math.Round(posAndAngel.Key.x), (int)Math.Round(posAndAngel.Key.y))
                , posAndAngel.Value);

            double speed = myController.GetCarSpeed();
            string[] speedText = this.myController.GetCarSpeed().ToString().Split(".,".ToCharArray());
            this.label_speed.Text = speedText[0];

            Console.Beep(100 + (int)speed * 2, graphicViewTimer.Interval - (graphicViewTimer.Interval * 3 / 4 * (150 - (int)speed) / 150));
        }

        /*private Image GenerateBitmapFromMatrix(Matrix m)
        {
            Bitmap image = new Bitmap(m.Columns, m.Rows);

            for (int i = 0; i < image.Width; ++i)
            {
                for (int j = 0; j < image.Height; ++j)
                {
                    image.SetPixel(i, j, Map.GetSurface(i, j).texture.GetPixel(i % Map.GetSurface(i, j).texture.Width, j % Map.GetSurface(i, j).texture.Height));
                }
            }

            return image;
        }*/

        private void button_ai_start_Click(object sender, EventArgs e)
        {
            graphicViewTimer.Start();
        }

        private void button_ai_stop_Click(object sender, EventArgs e)
        {            
            graphicViewTimer.Stop();
            myController.Reset();
            myGraphicPanel.ResetCar();
        }

        private void button_ai_teach_Click(object sender, EventArgs e)
        {
            myDriver.Teach((int)numericUpDown_iterations.Value);

            button_ai_stop_Click(null, null);
        }

        private void button_ai_load_Click(object sender, EventArgs e)
        {
            myDriver.LoadProfile(textBox_AiFileName.Text);
        }

        private void button_ai_save_Click(object sender, EventArgs e)
        {
            myDriver.SaveProfile(textBox_AiFileName.Text);
        }

        private void textBox_AiFileName_Click(object sender, EventArgs e)
        {
            AIProfileopenFileDialog.ShowDialog(this);
            textBox_AiFileName.Text = AIProfileopenFileDialog.FileName;
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            myGraphicPanel.BackgroundImage = new Bitmap(System.Windows.Forms.Application.StartupPath + "\\Data\\hungaroring_gen.bmp");
            myGraphicPanel.BackgroundImageLayout = ImageLayout.None;

            Map.LoadFromTextFile(System.Windows.Forms.Application.StartupPath + "\\Data\\hungaroring_gen.txt");

            myController.MapLoaded();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

    }
}